home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / GAMES / P_ROBO31 / SBOMBER.PR < prev    next >
Text File  |  1993-02-20  |  7KB  |  212 lines

  1.   PROCEDURE SBomber;  {Stealth Bomber}
  2.   {
  3.    Author: David Malmberg
  4.  
  5.    Strategy:  Place bombs in the middle of the field then go to a random
  6.    corner with cloak raised.  Scan for an enemy near the bomb.  If you
  7.    spot one, then detonate the bomb and begin again with another bomb.
  8.  
  9.    If you see an enemy in missile range (but not near the bomb) blast 'em.
  10.   }
  11.  
  12. (* Below are the SBomber options as specified in the SBOMBER.CFG file
  13.  
  14.    Radar := 3;
  15.    Fuel := 0;
  16.    Engine := 0;
  17.    Armor := 0;
  18.    Warheads := 1;
  19.    Bombs := 1;
  20.    Shielding := 0;
  21.    Cloaking := 5;
  22.    Repairing := 0;
  23. *)
  24.  
  25.   CONST
  26.     NW_Corner = 1;
  27.     NE_Corner = 2;
  28.     SW_Corner = 3;
  29.     SE_Corner = 4;
  30.  
  31.   VAR { SBomber "Global" variables }
  32.  
  33.     Angle, { Scanning angle }
  34.     Last_Damage, { Robot's Last damage value }
  35.     D_Speed, { Robot's desired speed }
  36.     D_Heading, { Robot's desired heading }
  37.     BombX, BombY, {Bomb's Co-ordinates}
  38.     BombAngle, BombRange, {Angle and Distance from current corner to Bomb}
  39.     LastTime, { Last Time cycles were measured }
  40.     Delta          : Integer; { Scanning arc }
  41.  
  42.     CornerX : ARRAY[1..4] OF Integer; {X coordinate of Corners}
  43.     CornerY : ARRAY[1..4] OF Integer; {Y coordinate of Corners}
  44.     StartAngle : ARRAY[1..4] OF Integer; {Starting scanning angles for Corners}
  45.  
  46.     Corner, { Current Corner }
  47.     Range   { Range/Distance to foe }  : Integer;
  48.  
  49.     BombHasExploded : Boolean;
  50.  
  51.     PROCEDURE Initialize;
  52.     BEGIN
  53.       CornerX[NW_Corner] := 10;
  54.       CornerY[NW_Corner] := 990;
  55.       StartAngle[NW_Corner] := 270;
  56.  
  57.       CornerX[NE_Corner] := 990;
  58.       CornerY[NE_Corner] := 990;
  59.       StartAngle[NE_Corner] := 180;
  60.  
  61.       CornerX[SW_Corner] := 10;
  62.       CornerY[SW_Corner] := 10;
  63.       StartAngle[SW_Corner] := 0;
  64.  
  65.       CornerX[SE_Corner] := 990;
  66.       CornerY[SE_Corner] := 10;
  67.       StartAngle[SE_Corner] := 90;
  68.     END; {Initialize}
  69.  
  70.     PROCEDURE Aim(VAR Ang : Integer; VAR Arc : Integer);
  71. {
  72.  Improve aim by doing a binary search of the target area.
  73.  I.E., divide the target area in two equal pieces and redefine
  74.  the target area to be the piece where the foe is found.
  75.  If the foe is not found, expand the search area to the
  76.  maximum arc of plus or minus 10 degrees.
  77. }
  78.     BEGIN
  79.       Arc := Arc DIV 2; { Divide search area in two. }
  80.       IF scan(Ang-Arc, Arc) <> 0 { Check piece "below" target angle. }
  81.         THEN Ang := Ang-Arc { If foe found, redefine target angle. }
  82.         ELSE IF scan(Ang+Arc, Arc) <> 0 { Check piece "above" target angle. }
  83.           THEN Ang := Ang+Arc { If foe found, redefine target angle. }
  84.           ELSE Arc := 10;
  85.       { Foe not found in either piece, expand search area to maximum arc. }
  86.     END; {Aim}
  87.  
  88.     PROCEDURE BlastThem;
  89.     BEGIN
  90.       Angle := 10;
  91.       REPEAT
  92.         Delta := 10; { Start with widest scanning arc. }
  93.         Range := scan(Angle, Delta);
  94.         WHILE (Range > 40) AND (ObjectScanned = Enemy)
  95.           AND (Range < MaxMissileRange) DO
  96.         { Must be far enough away to avoid self-damage. }
  97.           BEGIN
  98.             Aim(Angle, Delta); { Improve aim. }
  99.             Cannon(Angle, Range); { Fire!! }
  100.             Range := scan(Angle, Delta); { Is foe still in sights? }
  101.           END;
  102.         Angle := Angle+20; { Look in adjacent target area. }
  103.       UNTIL Angle > 360;
  104.     END;
  105.  
  106.     PROCEDURE GOTO(x, y : Integer);
  107.       { Go to location X,Y on playing field. }
  108.     VAR Heading    : Integer;
  109.     BEGIN
  110.       LowerCloak; {Less need for Cloak while moving}
  111.  
  112.       { Find the heading we need to get to the desired spot. }
  113.       Heading := Angle_To(x, y);
  114.  
  115.       { Keep traveling at top speed until we are within 150 meters }
  116.       WHILE (distance(loc_x, loc_y, x, y) > 150) DO
  117.         BEGIN
  118.           Drive(Heading, MaxSpeed);
  119.           BlastThem;
  120.         END;
  121.  
  122.       { Cut speed, and creep the rest of the way. }
  123.       WHILE (distance(loc_x, loc_y, x, y) > 20) DO
  124.         BEGIN
  125.           Drive(Heading, 20);
  126.           BlastThem;
  127.         END;
  128.  
  129.       { Stop driving, should coast to a stop. }
  130.       Drive(Heading, 0); {I.E., Stop}
  131.       RaiseCloak; {Need Cloak while stopped}
  132.     END; {GoTo(X,Y)}
  133.  
  134.     FUNCTION Hurt  : Boolean;
  135.       { Checks if Robot has incurred at least 5 points of new damage. }
  136.     VAR Curr_Damage : Integer;
  137.       Answer         : Boolean;
  138.     BEGIN
  139.       Curr_Damage := damage;
  140.       Answer := (Curr_Damage > (Last_Damage + 4));
  141.       Last_Damage := Curr_Damage;
  142.       IF Answer THEN LastTime := Time;
  143.       Hurt := Answer;
  144.     END; {Hurt}
  145.  
  146. PROCEDURE PlaceTheBomb;
  147.   BEGIN {PlaceTheBomb}
  148.     BombHasExploded := FALSE;
  149.     GoTo(500,500);
  150.     BombX := Loc_X;
  151.     BombY := Loc_Y;
  152.     PlaceBomb;
  153.   END; {PlaceTheBomb}
  154.  
  155. FUNCTION EnemyNearBomb : Boolean;
  156. CONST PlusMinus = 200;
  157. VAR EnemyDistance : Integer;
  158.     Answer : Boolean;
  159.   BEGIN
  160.     Answer := FALSE;
  161.     EnemyDistance := Scan(BombAngle, 10);
  162.     IF ObjectScanned <> Enemy THEN EnemyDistance := 0;
  163.     IF EnemyDistance > 0
  164.        THEN Answer := (EnemyDistance > (BombRange - PlusMinus))
  165.                          AND (EnemyDistance < (BombRange + PlusMinus));
  166.     EnemyNearBomb := Answer;
  167.   END; {EnemyNearBomb}
  168.  
  169. PROCEDURE Do_Corner;
  170.   BEGIN {Do_Corner}
  171.     Angle := StartAngle[Corner] + 10; {Starting angle for scanning}
  172.     REPEAT
  173.       IF EnemyNearBomb
  174.         THEN BEGIN
  175.           Detonate;
  176.           BombHasExploded := TRUE;
  177.         END;
  178.       Range := scan(Angle, Delta);
  179.       WHILE (Range > 40) AND (Range < MaxRadarRange) DO
  180.         { Must be far enough away to avoid self-damage. }
  181.         BEGIN
  182.           IF ObjectScanned = Enemy THEN cannon(Angle, Range); { Fire!! }
  183.           Range := scan(Angle, Delta); { Is foe still in sights? }
  184.         END;
  185.       Angle := Angle + 20; { Look in adjacent target area. }
  186.       IF (Angle > (StartAngle[Corner] + 90))
  187.         THEN Angle := StartAngle[Corner] + 10;
  188.     UNTIL BombHasExploded;
  189.   END; {Do_Corner}
  190.  
  191.  
  192.   BEGIN {SBomber Main}
  193.     RaiseCloak;
  194.     Initialize;
  195.     Delta := 10; { The widest possible scanning arc. }
  196.     LastTime := Time;
  197.     REPEAT { Until Dead or Winner }
  198.       PlaceTheBomb;
  199.       Corner := Random(3) + 1; {Pick a corner}
  200.       GoTo(CornerX[Corner], CornerY[Corner]);
  201.       { Move to selected corner. }
  202.       BombAngle := Angle_To(BombX, BombY);
  203.       BombRange := Distance(Loc_X, Loc_Y, BombX, BombY);
  204.       { Determine relative location from corner to Bomb }
  205.       Do_Corner;
  206.       IF Hurt THEN
  207.          IF Fuel > 250
  208.            THEN RaiseCloak { Raise cloak and flee! }
  209.            ELSE LowerCloak;
  210.     UNTIL Dead OR Winner;
  211.   END; {SBomber Main}
  212.